/*
    Carracci Systems - Carracci Server (openbam project)
    Copyright (C) 2007  Carracci Systems

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.openbam.core.expr;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.openbam.core.Event;

public abstract class BinaryExpression extends Expression {
	protected Log log = LogFactory.getLog(this.getClass());
	
	protected Expression lhs;
	protected Expression rhs;
	protected Object value;

    public Expression getLhs() {
		return lhs;
	}
	public void setLhs(Expression lhs) {
		this.lhs = lhs;
	}
	public Expression getRhs() {
		return rhs;
	}
	public void setRhs(Expression rhs) {
		this.rhs = rhs;
	}
	
	public Object evaluate(Event event) {
		Object o = null;
		value= null;
        
        Object lhsValue = null;
		Object rhsValue = null;
		
		try {
			lhsValue = lhs.evaluate(event);
			rhsValue = rhs.evaluate(event);
			
			o = operate(lhsValue, rhsValue);
		} 
		catch (Exception e) {
			if (log.isDebugEnabled()) {
				log.debug(this.getName() + " evaluation failed due to: lhsValue=" + lhsValue + " rhsValue=" + rhsValue);
			}
			if (log.isTraceEnabled()) {
				log.trace("Associated exception is: " + e.getMessage(), e);
			}
		}
		
		if (log.isTraceEnabled()) {
			log.trace(new StringBuilder().append(getName())
						.append("(").append(lhsValue).append(" , ")
						.append(rhsValue).append(")")
						.append(" = ").append(o));
		}
        value = o;
        return o;
	}
	
	protected abstract Object operate(Object lhsValue, Object rhsValue);
	
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(this.getName()).
				append("(").
				append(lhs.toString()).
				append(", ").
				append(rhs.toString()).
				append(")");
		
		return builder.toString();
	}


    public Object getValue() {
        return value;
    }
}

